package com.example.demo.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

@Slf4j
@Aspect
@Component
public class ValidateAspect {

    @Pointcut("execution(* com.example.demo.controller*.*(..))")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        HttpServletRequest httpRequest = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();

        Object[] args = joinPoint.getArgs();
        if (args != null && args.length > 0) {
            for (Object arg : args) {
                // 校验 入参
                if (arg instanceof IRequest) {
                    IRequest<?> iRequest = (IRequest<?>) arg;
                    try {
                        iRequest.check();
                    } catch (CheckedException e) {
                        Class<? extends IResponse> responseType = iRequest.getResponseClass();
                        IResponse response = responseType.newInstance();
                        response.setCodeAndMessage(-1, e.getMessage());
                        return response;
                    }
                }
            }
        }

        Object object = joinPoint.proceed();

        String url = httpRequest.getRequestURL().toString();
        long duration = System.currentTimeMillis() - startTime;
        log.info("环绕通知结束，请求URL:【{}】, 耗时：【{}】", url, duration);
        return object;
    }
}
